/*
 * DA4.c
 *
 * Created: 4/12/2015 5:35:39 AM
 *  Author: David Hunt
 */ 
	#include <avr/io.h>
	#include <stdint-gcc.h>
	
	#define XTAL 16000000L 
	
	static void delay(uint16_t us)
	{
		while ( us ) us--;
	}
	
	int main(void)
	{
		uint8_t i = 0;
		uint8_t t = 0;
		
		DDRB = 0xff; // use all pins on PortB for output
		DDRD = 0xff; // and portD
		PORTB = 0x00; // set output high -> turn all LEDs off
		PORTD = 0x00;

		//fast PWM with OCR0A as top, non-inverting mode, no prescale
		TCCR0A |= (1<<COM0A1) | (1<<WGM01) | (1<<WGM00);
		TCCR0B |= (1<<WGM02) | (1<<CS00);

		//select non-inverted PWM, fast PWM with clk/8 prescale and ICR1 as top
		TCCR1A |= (1<< WGM11) | (1<<COM1A1) | (1<<COM1B1);
		TCCR1B |= (1<<CS11) | (1<<WGM12) | (1<<WGM13);
		
		//fast PWM with OCR0A as top, non-inverting mode, no prescale
		TCCR2A |= (1<<COM2A1) | (1<<WGM21) | (1<<WGM20);
		TCCR2B |= (1<<WGM22) | (1<<CS20);
		
		for (;;){
			
			//PWM timer0
			for (t=10; t<250; t+10){ //for each frequency from 10 to 250 by 10
				OCR0A=t;
				
				// dim LED on
				for (i=0; i<t; i++){
					OCR0B = i; //set duty cycle
					delay(XTAL/1600); //delay 10 ms 
				}
				// dim LED off
				for( i=t; i>0; i--){
					OCR0B = i; //set duty cycle
					delay(XTAL/1600); //delay 10 ms
				}
			}			
			
			//PWM timer1
			for (t=10; t<250; t+10){	//for each frequency from 10 to 250 by 10
				ICR1=t;
				
				// dim LED on
				for (i=0; i<t; i++){
					OCR1AL = i; //set duty cycle
					delay(XTAL/1600); //delay 10 ms
				}
				//dim LED off
				for( i=t; i>0; i--){
					OCR1AL = i; //set duty cycle
					delay(XTAL/1600); //delay 10 ms
				}
			}
			
			//PWM Timer 2
			for (t=10; t<250; t+10){	//for each frequency from 10 to 250 by 10
				OCR2A=t;	//set max to current period
				
				//dim LED on
				for (i=0; i<t; i++){
					OCR2B = i; //set duty cycle
					delay(XTAL/1600); //delay 10 ms
				}
				// dim LED off
				for( i=t; i>0; i--){
					OCR2B = i; //set duty cycle
					delay(XTAL/1600); //delay 10 ms
				}
			}
		}
		return 0;
	}